use crate::codec::d_codec::{Packet, PacketBytesCodec, Transmission};
use crate::start::server::Message;
use bytes::{Buf, Bytes};
use std::net::SocketAddr;

use crate::start::tcp::TcpConnection;
use crate::start::Connection;
use futures::future::ok;
use futures::task::Poll;
use futures::{Future, SinkExt, StreamExt};
use lazy_static::lazy_static;
use loom::sync::atomic::AtomicU8;
use std::cell::RefCell;
use std::marker::PhantomData;
use std::sync::Arc;
use std::task;
use tokio_util::codec::Decoder;

// lazy_static! {
//     pub static ref DISPATCHER_MANAGER: Vec<fn <T, U, S>(PacketTransmissionMessage<T, U, S>) -> Option<ReplyMessage<T>>> = vec![];
// }
// fn tg<T, U, S>(p: PacketTransmissionMessage<T, U, S>) -> Option<ReplyMessage<T>> {}

pub(crate) trait Handler: Sync + Send {
    fn handler(&self, con: Connection);
}

pub struct FnHandler<F>
where
    F: Fn(Connection),
{
    f: F,
}
impl<F> FnHandler<F>
where
    F: Fn(Connection),
{
    pub(crate) fn new(f: F) -> Self {
        Self { f }
    }
}

impl<F> Handler for FnHandler<F>
where
    F: Fn(Connection) + Sync + Send,
{
    fn handler(&self, con: Connection) {
        (self.f)(con)
    }
}
#[derive(Default)]
pub struct PacketDispatcher {
    pub(crate) dispatchers: std::collections::HashMap<i16, Box<dyn Handler>>,
}

// impl Clone for PacketDispatcher {
//     fn clone(&self) -> Self {
//         let mut map: std::collections::HashMap<i16, Box<dyn Handler>> =
//             std::collections::HashMap::new();
//         for (k, v) in &self.dispatchers {
//             map.insert(k, v);
//         }
//         PacketDispatcher { dispatchers: map }
//     }
// }

impl PacketDispatcher {
    pub fn dispatcher(&self, con: Connection) {
        //      消息分发
        let map = &self.dispatchers;
        let mut option = map.get(&con.packet.get_cmd());
        if let Some(f) = option{
            f.handler(con);
            // f.handler(con);
        } else {
            println!("not fount cmd map fn")
        };
    }
    pub fn register<F: 'static + Fn(Connection) + Sync + Send>(&mut self, k: i16, f: F) {
        //  消息注册
        let mut map = &mut self.dispatchers;
        map.insert(k, Box::new(FnHandler::new(f)));
    }
}

#[test]
fn test() {
    let mut dispatcher = PacketDispatcher::default();
    let y = |con: Connection| {
        con.packet.get_body();
    };
    let y = |con: Connection| {
        con.packet.get_body();
    };
    fn ff(c: Connection) {}
    fn te(f: fn(Connection)) -> Box<dyn Handler> {
        struct te;
        impl Handler for te {
            fn handler(&self, con: Connection) {
                // f(con)
            }
        }
        Box::new(te)
    }
    dispatcher.register(1, y);
    dispatcher.register(2, ff);
    dispatcher.register(4, y);
    println!("{:}", 1);
}
// #[async_trait]
// impl<C, T, U> Dispatcher<C, T, U> for PacketDispatcher
// where
//     C: Connection<T, U, Send = Message<T>>,
//     T: TransportObj + TransportPackage<EncodeObj = T>,
//     U: Decoder,
// {
//     fn dispatcher(packet: T, addr: SocketAddr, connection: &C) {
//         pub struct Error {
//             cause: Box<dyn std::error::Error>,
//         }
//
//         pub fn default_service<
//             'a,
//             T: TransportObj + TransportPackage<EncodeObj = T>,
//             U: Decoder,
//             S,
//         >() -> impl Service<PacketTransmissionMessage<'a, T, U, S>, Response = Bytes, Error = Error>
//         where
//             T: 'a,
//             U: 'a,
//             S: 'a,
//         {
//             (move |req: PacketTransmissionMessage<T, U, S>| {
//                 // println!("aaaaaa");
//                 ok(Bytes::new())
//             })
//             .into_service()
//         }
//
//         let mut service = default_service::<T, U, Bytes>();
//         //todo
//         // 1.判断cmd ，如果不是转发走以下流程
//         // 2.根据序列化进行判断反序列化
//         // 3.获取到body后进行dispatcher分发到对应的方法中
//         let serialization_type = packet.get_serialization_type();
//         if let Some(ser) = SERIALIZATION_MANAGER.get(serialization_type as usize) {}
//         let serialized = SERIALIZATION_MANAGER
//             .get(serialization_type as usize)
//             .unwrap();
//         // std::thread::spawn()
//         // let msg_obj = serialized.deserialized(
//         //     packet
//         //         .get_body()
//         //         .copy_to_bytes(packet.get_body_length() as usize),
//         // );
//         // let vec1 = vec![];
//
//         // DISPATCHER_MANAGER
//         // let message = PacketTransmissionMessage::<'a, T, U, S>::new(
//         //     packet,
//         //     AtomicU8::new(0),
//         //     connection,
//         //     serialized,
//         //     msg_obj,
//         //     addr,
//         // );
//         // message.send(Bytes::new(), Some(JsonSerialization));
//         // connection.send(Message::Send(packet.cover_send(), addr));
//     }
// let mut x = &<C as Connection>::Send;
// x.send(packet,addr);
// }
